package cn.edu.buaa.treehole.service;

import cn.edu.buaa.treehole.dao.UserDao;
import cn.edu.buaa.treehole.pojo.dao.UserDaoInfo;
import cn.edu.buaa.treehole.pojo.network.user.UserChangeInfoRequestInfo;
import cn.edu.buaa.treehole.pojo.network.user.UserLoginRequestInfo;
import cn.edu.buaa.treehole.pojo.network.user.UserSignUpRequestInfo;
import cn.edu.buaa.treehole.service.exception.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.List;

@Service
public class UserService {
    public static final int PASSWORD_MAX_LENGTH = 16;
    public static final int EMAIL_MAX_LENGTH = 32;
    private final UserDao userDao;

    @Autowired
    public UserService(UserDao userDao) {
        this.userDao = userDao;
    }

    public void addUser(UserSignUpRequestInfo info) throws SignatureTooLongException, PasswordTooLongException, EmailTooLongException, EmailUsedException {
        if (info.getDefaultSignature().length() > SignatureService.SIGNATURE_MAX_LENGTH) {
            throw new SignatureTooLongException("too long signature as default-signature of user");
        }
        if (info.getPassword().length() > PASSWORD_MAX_LENGTH) {
            throw new PasswordTooLongException();
        }
        if (info.getEmail().length() > EMAIL_MAX_LENGTH) {
            throw new EmailTooLongException();
        }
        if (userDao.selectAllUserByEmail(info.getEmail()).size() != 0) {
            throw new EmailUsedException();
        }
        UserDaoInfo userDaoInfo = new UserDaoInfo();
        userDaoInfo.setAuto(info.getDefaultSignature());
        userDaoInfo.setEmail(info.getEmail());
        userDaoInfo.setPassword(info.getPassword());
        long uid = userDao.selectMaxUid() + 1;
        //System.out.println("uid=" + uid);
        userDaoInfo.setUid(uid);
        userDao.insertUser(userDaoInfo);
    }

    public String getDefaultSignature(long uid) {
        return userDao.selectUserByUid(uid).getAuto();
    }

    public void login(
            UserLoginRequestInfo info,
            HttpSession session,
            HttpServletRequest request,
            HttpServletResponse response) throws PasswordWrongException {
        UserDaoInfo userDaoInfo = userDao.selectUserByEmail(info.getEmail());
        if (!userDaoInfo.getPassword().equals(info.getPassword())) {
            throw new PasswordWrongException();
        }
        session.setAttribute("uid", userDaoInfo.getUid());
        Cookie cookie = new Cookie("uid", String.valueOf(userDaoInfo.getUid()));
        cookie.setMaxAge(7 * 24 * 60 * 60);     // 7 天失效
        cookie.setDomain(request.getContextPath());
        response.addCookie(cookie);
    }

    public void logout(
            HttpSession session,
            HttpServletRequest request,
            HttpServletResponse response) {
        session.removeAttribute("uid");
        Cookie cookie = new Cookie("uid", "");
        cookie.setMaxAge(0);
        cookie.setDomain(request.getContextPath());
        response.addCookie(cookie);
    }

    public long loginCheck(HttpServletRequest request, HttpSession session) throws NeedLoginException {
        try {
            Cookie[] cookies = request.getCookies();
            long uid = -1;
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("uid")) {
                    uid = Long.parseLong(cookie.getValue());
                    break;
                }
            }
            if (uid == -1) {
                throw new NeedLoginException();
            }
            Object obj = session.getAttribute("uid");
            if (obj == null) {
                session.setAttribute("uid", uid);
            }
            return uid;
        } catch (Exception e) {
            throw new NeedLoginException(e);
        }
    }

    public void change_info(long uid, UserChangeInfoRequestInfo info) throws PasswordWrongException, PasswordTooLongException, SignatureTooLongException {
        UserDaoInfo oldInfo = userDao.selectUserByUid(uid);
        if (!oldInfo.getPassword().equals(info.getOldPassword())) {
            throw new PasswordWrongException();
        }
        if (info.getDefaultSignature().length() > 0) {
            if (info.getDefaultSignature().length() > SignatureService.SIGNATURE_MAX_LENGTH) {
                throw new SignatureTooLongException();
            }
            userDao.updateDefaultSignature(uid, info.getDefaultSignature());
        }
        if (info.getNewPassword().length() > 0) {
            if (info.getNewPassword().length() > PASSWORD_MAX_LENGTH) {
                throw new PasswordTooLongException();
            }
            userDao.updatePassword(uid, info.getNewPassword());
        }
    }
}
